#include "precompile.h"

#include "Workspace.h"
#include "workspace/IDocument.h"
#include "Document.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

Workspace::Workspace()
{
}

Workspace::~Workspace()
{
}

vresult Workspace::Create(const String& workpath)
{
	m_workpath = workpath;
	return vok;
}

void Workspace::Close() 
{
	::UnloadAllComponents();
}

IDocument* Workspace::NewDocument(documentCategory category,
																	  pageTypesetCategory pageTypeset,
																	  pageBindingCategory pageBinding,
																	  uint32 pageCount,
																	  real pageHeight,
																	  real pageWidth,
																	  real pageLeftMargin,
																	  real pageTopMargin,
																	  real pageRightMargin,
																	  real pageBottonMargin)
{
	wchar_t buffer[256];
	_itow_s(GetNewDocumentCount(),buffer,256,10);
	String docname = buffer;
	if (DocumentCreating())
		DocumentCreating()(sys::getSelf<IWorkspace>(this),docname);

	sys::ObjectPtr objDocument;
	objDocument.CreateObject(CLSID_Document);
	sys::InterfacePtr<IDocument> pIFDocument(objDocument);
	Document* document = (Document*)pIFDocument.P();
	if (ISFAILED(document->New(docname,this,category,pageTypeset,pageBinding,pageCount,pageHeight,pageWidth,pageLeftMargin,pageTopMargin,pageRightMargin,pageBottonMargin)))
		return NULL;

	m_documents[docname] = objDocument;

	if (DocumentCreated())
		DocumentCreated()(sys::getSelf<IWorkspace>(this),docname);

	return pIFDocument;
}

IDocument* Workspace::OpenDocument(const String& documentName)
{
	String docname = documentName;
	if (DocumentOpening())
		DocumentOpening()(sys::getSelf<IWorkspace>(this),docname);

	sys::ObjectPtr objDocument;
	objDocument.CreateObject(CLSID_Document);
	sys::InterfacePtr<IDocument> pIFDocument(objDocument);

	Document* document = (Document*)pIFDocument.P();
	if (ISFAILED(document->Open(docname,this)))
		return NULL;

	m_documents[docname] = objDocument;

	if (DocumentOpened())
		DocumentOpened()(sys::getSelf<IWorkspace>(this),docname);

	return pIFDocument;
}

vresult Workspace::CloseDocument(const String& documentName)
{
	Documents::iterator itfind = m_documents.find(documentName);
	if (itfind != m_documents.end())
	{
		if (DocumentClosing())
			DocumentClosing()(sys::getSelf<IWorkspace>(this),documentName);

		sys::InterfacePtr<IDocument> pIFDocument(itfind->second);
		Document* document = (Document*)pIFDocument.P();
		if (ISFAILED(document->Close()))
			return vfailed;

		if (DocumentClosed())
			DocumentClosed()(sys::getSelf<IWorkspace>(this),documentName);

		m_documents.erase(itfind);

		return vok;
	}
	return vfailed;
}

IDocument* Workspace::FindDocument(const String& documentName) const
{
	Documents::const_iterator itfind = m_documents.find(documentName);
	if (itfind != m_documents.end())
		return sys::InterfacePtr<IDocument>(itfind->second);

	return NULL;
}

IDocument* Workspace::GetDocument(uint32 index) const
{
	ASSERT(GetDocumentsCount() > 0 && index < GetDocumentsCount());

	Documents::const_iterator iter = m_documents.begin();
	std::advance(iter,index);
	return sys::InterfacePtr<IDocument>(iter->second);
}

uint32 Workspace::GetDocumentsCount() const
{
	return m_documents.size();
}

void Workspace::UpdateDocumentName(const String& documentName)
{
	Documents::iterator itfind = m_documents.find(documentName);
	if (itfind == m_documents.end())
	{
		sys::ObjectPtr document = itfind->second;
		m_documents.erase(itfind);
		m_documents[documentName] = document;
	}
}

int Workspace::GetNewDocumentCount() const
{
	int count = 0;
	Documents::const_iterator itbegin = m_documents.begin();
	Documents::const_iterator itend = m_documents.end();
	for (; itbegin != itend; ++itbegin)
	{
		sys::InterfacePtr<IDocument> pIFDocument(itbegin->second);
		if(pIFDocument->IsNew())	
			count++;
	}
	return count;
}